﻿
using System;
using System.Linq;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Threading.Tasks;

using FreeSql;
using Kalman;
using Newtonsoft.Json.Linq;
using TencentCloud.Cynosdb.V20190107.Models;
using Kalman.Extensions;
using NLog.LayoutRenderers.Wrappers;

namespace QuDao
{
    /// <summary>
    /// 提现申请业务对象（处理数据表biz_cash_apply相关的业务逻辑）
    /// </summary>
    public sealed partial class CashApplyBO : SingletonBase<CashApplyBO>
    {
        readonly IFreeSql fsql;
        public CashApplyBO() : base()
        {
            fsql = ServiceLocator.Instance.GetRequiredService<IFreeSql>();
        }
        
        /// <summary>
        /// 获取提现申请
        /// </summary>
        /// <param name="id">主键ID的值</param>
        /// <returns></returns>
        public T GetItem<T>(long id)
        {
        	if (id <= 0) return default;
            var item = fsql.Select<CashApply>().Where(a => a.ID == id).ToOne<T>();
            return item;
        }
        
        public CashApply GetItem(long id)
        {
        	return GetItem<CashApply>(id);
        }
        
        /// <summary>
        /// 获取用提现申请数据列表
        /// </summary>
        /// <param name="uid">用户ID</param>
        /// <param name="pageIndex">页索引，从1开始</param>
        /// <param name="pageSize">每页记录数，默认10</param>
        /// <returns></returns>
        public List<CashApplyDto> GetList(long uid, int pageIndex = 1, int pageSize = 10)
        {
            var list = fsql.Select<CashApply>()
                .Where(a => a.UserID == uid)
                .Page(pageIndex, pageSize)
                .OrderByDescending(a => a.ID)
                .ToList<CashApplyDto>();
            return list;
        }
        
        /// <summary>
        /// 获取提现申请数据列表
        /// </summary>
        /// <returns></returns>
        public List<T> GetList<T>(long[] ids)
        {
        	if (ids == null || ids.Length == 0) return new List<T>();
            var list = fsql.Select<CashApply>().Where(a => ids.Contains(a.ID)).ToList<T>();
            return list;
        }

        /// <summary>
        /// 新增提现申请
        /// </summary>
        public long Add(long uid, decimal amount)
        {
            var user = UserBO.Instance.GetItem<User>(uid) ?? throw new AppException($"用户不存在：{uid}");
            if (user.Balance < amount) throw new AppException("提现金额不能大于账户余额");
            if (user.ClearingBank.IsNullOrEmpty() || user.BankAccountName.IsNullOrEmpty() || user.BankCardNo.IsNullOrEmpty()) throw new AppException("结算银行信息未完善");

            var entity = new CashApply
            {
                TID = user.TID,
                Amount = amount,
                Target = 1,
                UserID = user.UserID,
                TrueName = user.TrueName,
                Status = 0,
                CreateTime = DateTime.Now,
                Memo = $"{user.BankAccountName}-{user.ClearingBank}{user.BankCardNo}"
            };

            fsql.Transaction(() =>
            {
                entity.ID = (long)fsql.Insert(entity).ExecuteIdentity();
                fsql.Update<User>(uid).Set(a => a.Balance - amount).ExecuteAffrows();
            });

            return entity.ID;
        }

        /// <summary>
        /// 确认打款
        /// </summary>
        /// <param name="id"></param>
        /// <param name="tradeNo"></param>
        /// <param name="paymentTime"></param>
        /// <param name="operatorID"></param>
        /// <exception cref="AppException"></exception>
        public void Confirm(long id, string tradeNo, DateTime paymentTime, long operatorID)
        {
            var item = GetItem(id) ?? throw new AppException($"提现申请记录不存在：{id}");
            var user = UserBO.Instance.GetItem(operatorID) ?? throw new AppException($"操作员不存在：{operatorID}");

            fsql.Update<CashApply>(id)
                .Set(a => a.Target, 1) //提现到银行卡
                .Set(a => a.Status, 1)
                .Set(a => a.TradeNo, tradeNo)
                .Set(a => a.PaymentTime, paymentTime.Date)
                .Set(a => a.OperatorID, operatorID)
                .Set(a => a.OperatorName, user.TrueName)
                .Set(a => a.CreateTime, DateTime.Now)
                .ExecuteAffrows();
        }

        /// <summary>
        /// 获取指定月份体现总金额
        /// </summary>
        /// <param name="tid"></param>
        /// <param name="date"></param>
        /// <returns></returns>
        public decimal GetSummaryByMonth(int tid, DateTime date)
        {
            var minDate = date.GetFirstDay();
            var maxDate = date.GetLastDay();

            var result = fsql.Select<CashApply>()
                .Where(a => a.TID == tid && a.CreateTime >= minDate && a.CreateTime <= maxDate)
                .ToAggregate(a => new { Amount = a.Sum(a.Key.Amount) });

            return result.Amount;
        }


        ///// <summary>
        ///// 删除提现申请数据
        ///// </summary>
        ///// <returns>返回影响行数</returns>
        //public int Delete(long[] ids)
        //{
        //	if (ids == null || ids.Length == 0) return 0;
        //	return fsql.Delete<CashApply>().Where(a => ids.Contains(a.ID)).ExecuteAffrows();
        //}

        ///// <summary>
        ///// 删除提现申请数据
        ///// </summary>
        ///// <returns>返回影响行数</returns>
        //public int Delete(long id)
        //{
        //	return fsql.Delete<CashApply>(id).ExecuteAffrows();
        //}

        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="req">分页查询请求对象</param>
        public PagingResult<CashApply> Query(PagingRequest req, int tid, DateTime beginDate, DateTime endDate)
        {
        	if (req == null) throw new AppException("查询数据不能为空");
        	
            var select = fsql.Select<CashApply>()
                .Where(a => a.CreateTime >=  beginDate.Date && a.CreateTime <= endDate.Date.AddDays(1))
                .WhereIf(tid > 0, a => a.TID == tid);
            foreach (var item in req.FilterItems)
            {
                switch (item.Field)
                {
                    case "ID":
                        select.Where(a => a.ID == long.Parse(item.Value));
                        break;
                    //case "CashApplyName":
                    //    select.Where(a => a.CashApplyName.Contains(item.Value));
                    //    break;
                    default:
                        break;
                }
            }

            if (!string.IsNullOrEmpty(req.SortExp))
            {
                select.OrderBy(req.SortExp);//自定义排序
            }
            else
            {
                select.OrderByDescending(a => a.ID);//默认排序
            }

            //var sql = select.ToSql();

            var list = select.Count(out var total).Page(req.PageIndex, req.PageSize).ToList<CashApply>();
            return new PagingResult<CashApply>
            {
                PageIndex = req.PageIndex,
                PageSize = req.PageSize,
                Data = list,
                Total = (int)total
            };
        }
        
    }
}
